﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;

namespace Limestone.Storage.XML
{
    public class FileReader:IFileReader
    {
        private readonly XmlReaderSettings _xmlReaderSettings;
        private readonly IXmlStorageConfig _xmlStorageConfig;

        public FileReader(XmlReaderSettings xmlReaderSettings, IXmlStorageConfig xmlStorageConfig)
        {
            _xmlReaderSettings = xmlReaderSettings;
            _xmlStorageConfig = xmlStorageConfig;
        }

        public IEnumerable<IPageStub> GetPageStubsFromDirectory(string directoryPath)
        {
            var di = new DirectoryInfo(directoryPath);
            var files = di.GetFiles("*.page");
            var directories = di.GetDirectories();

            // .page-files 
            var pages = ReadPageFiles(files);

            // directories 
            var folders = ReadPageDirectories(directories);

            return pages.Concat(folders);
        }

        private IEnumerable<IPageStub> ReadPageDirectories(IEnumerable<DirectoryInfo> directories)
        {
            return directories.Select(directoryInfo => ReadPageFile(Path.Combine(directoryInfo.FullName, _xmlStorageConfig.FolderIndexPageName + ".page")));
        }

        private IEnumerable<IPageStub> ReadPageFiles(IEnumerable<FileInfo> files)
        {
            return files.Where(fileInfo => Path.GetFileNameWithoutExtension(fileInfo.FullName).ToLower() != _xmlStorageConfig.FolderIndexPageName.ToLower()).Select(fileInfo => ReadPageFile(fileInfo.FullName));
        }

        public IPageStub ReadPageFile(string filePath)
        {
            if (!File.Exists(filePath))
                return null;

            using (var reader = XmlReader.Create(filePath, _xmlReaderSettings))
            {
                while (reader.Read())
                {
                    if (!reader.IsStartElement()) continue;

                    if (reader.IsEmptyElement || reader.Name != "Page") continue;

                    var name = reader.GetAttribute("Name");
                    if (string.IsNullOrEmpty(name))
                        return null;

                    return new PageStub()
                                    {
                                        Name = name,
                                        Path = reader.GetAttribute("Path"),
                                        Title = reader.GetAttribute("Title"),
                                        TemplatePath = reader.GetAttribute("TemplatePath"),
                                        Hidden = bool.Parse(reader.GetAttribute("Hidden")),
                                    };
                }
                return null;
            }
        }
    }
}
